// 60分 线段树
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int maxn = 50005;
const int MAX = 0x3f3f3f3f;

int n, a[maxn], last[maxn],
    pre[1000005]; // last记录每个点的前一个相同的点的位置，不存在记录为-1.

LL sum[maxn << 2], ans[maxn];

struct Query {
  int l, r, idx; // 结构体C用于存储区间的左端点、右端点和编号
};
Query querys[100005];

// 按照右端点排序的比较函数
bool cmp(Query a, Query b) { return a.r < b.r; }

// node ，l，r 为当前节点，左端点，右端点。
void build(int node, int l, int r) {
  if (l == r)
    sum[node] = a[l]; // 叶子节点直接赋值
  else {
    int m = (l + r) >> 1;
    build(2 * node, l, m);                         // 左子树
    build(2 * node + 1, m + 1, r);                 // 右子树
    sum[node] = sum[2 * node] + sum[2 * node + 1]; // 更新当前节点
  }
}

void update(int p, int node, int l, int r) {
  if (l == r) {
    sum[node] = 0; // 将叶子节点的值更新为0
    return;
  }
  int m = (l + r) >> 1;
  if (p <= m)
    update(p, 2 * node, l, m); // 更新左子树
  else
    update(p, 2 * node + 1, m + 1, r); // 更新右子树

  sum[node] = sum[2 * node] + sum[2 * node + 1]; // 更新当前节点
}

// 求出（x，y）区间的和,后面的参数为了计算方便而传入
//   node  为当前节点编号，，l，r表示这个节点所代表的区间左端点，右端点。
LL query(int x, int y, int node, int l, int r) {

  // 当前区间[x,y ]完全包含[l,r] 范围内
  if (x <= l && r <= y)
    return sum[node]; // 返回当前节点的值
  int m = (l + r) >> 1;
  LL res = 0;
  if (x <= m)
    res += query(x, y, 2 * node, l, m); // 查询左子树
  if (m < y)
    res += query(x, y, 2 * node + 1, m + 1, r); // 查询右子树
  return res;                                   // 返回查询结果
}

int main() {
  memset(pre, -1, sizeof(pre));   // 初始化pre数组
  memset(last, -1, sizeof(last)); // 初始化last数组
  scanf("%d", &n);                // 输入n
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    if (pre[a[i]] != -1) // 如果已经出现过
    {
      last[i] = pre[a[i]]; // 记录上一次出现的位置
      pre[a[i]] = i;       // 记录这一次位置
    } else
      pre[a[i]] = i; // 记录第一次出现的位置
  }
  int q;
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    scanf("%d%d", &querys[i].l, &querys[i].r); // 输入区间
    querys[i].idx = i;                         // 记录区间的编号
  }
  sort(querys + 1, querys + q + 1, cmp); // 按照右端点排序
  build(1, 1, n);                        // 建立线段树

  int fr = 1; // 记录当前处理的右端点
  for (int i = 1; i <= q; i++) {
    for (int j = fr; j <= querys[i].r; j++)
      if (last[j] != -1) {
        int p = last[j];
        update(p, 1, 1, n); // 点更新，值为0
      }
    int x = querys[i].l; // 更新A为当前区间的左端点
    int y = querys[i].r; // 更新B为当前区间的右端点
    ans[querys[i].idx] = query(x, y, 1, 1, n); // 区间查询
    fr = querys[i].r + 1; // 更新fr为下一个处理的右端点
  }
  for (int i = 1; i <= q; i++)
    printf("%lld\n", ans[i]); // 输出结果

  return 0; // 程序结束
}
